package com.cloudinnov.task;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.cloudinnov.dao.PreventionWorkOrderDao;
import com.cloudinnov.dao.SparepartPreventionConditionDao;
import com.cloudinnov.logic.EquipmentBomsLogic;
import com.cloudinnov.logic.EquipmentPointLogic;
import com.cloudinnov.logic.EquipmentsLogic;
import com.cloudinnov.logic.SparepartPreventionConfigLogic;
import com.cloudinnov.model.EquipmentBoms;
import com.cloudinnov.model.EquipmentPoints;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.PreventionWorkOrder;
import com.cloudinnov.model.SparepartPreventionCondition;
import com.cloudinnov.model.SparepartPreventionConfig;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.PropertiesUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @author liyijie
 * @date 2016年8月4日上午12:20:36
 * @email 37024760@qq.com
 * @remark 预防性维护。将点位实时数据和配置条件比较，达到条件就生成告警工单
 * @version 
 */
public class PreventQuartzJob {
	
	private int digit = 5;
	
	private static int EXECUTE_METHOD_COUNT ;
	
	private static final Logger logger = Logger.getLogger(InspectionQuartzJob.class);

	
	@Autowired
	private JedisPool jedisPool;
	
	@Autowired
	private SparepartPreventionConfigLogic sparepartPreventionConfigLogic;
	
	@Autowired
	private EquipmentsLogic equipmentsLogic;
	
	@Autowired
	private EquipmentBomsLogic equipmentBomsLogic;
	
	@Autowired
	private EquipmentPointLogic equipmentPointLogic;
	
	@Autowired
	private PreventionWorkOrderDao preventionWorkOrderDao;
	
	@Autowired
	private SparepartPreventionConditionDao sparepartPreventionConditionDao;
	
	private SparepartPreventionConfig sparepartPreventionConfig;
	
	private List<SparepartPreventionConfig> sparepartPreventionConfigList;
	
	protected void execute() {
		Jedis redis = null;
		try{
			//得到连接
			redis = jedisPool.getResource();
			//选库
			redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.pointvalue")));
			
			//每6分钟拿一次sparepart_prevention_config中的所有记录
			if(EXECUTE_METHOD_COUNT%6 == 0||EXECUTE_METHOD_COUNT == 0){
				sparepartPreventionConfigList = getSparepartPreventionConfigList();
			}
			EXECUTE_METHOD_COUNT++;
			
			//遍历sparepart_prevention_config中每条记录，看它是否达到默认报警值。
			for(int i = 0 ; i < sparepartPreventionConfigList.size() ; i++){
				SparepartPreventionConfig spConfig = sparepartPreventionConfigList.get(i);
				SparepartPreventionCondition  spCondition = null;
				String pointCode = spConfig.getPointCode();			
				int type = spConfig.getType();
				int useCount;
				int useTime;
				int warningValue;
				boolean isUseSpConfigWarningValue = true;
				
				int useWhichWarningValue = useWhichWarningValue(spConfig,redis);
				if(useWhichWarningValue == -1){
					warningValue = spConfig.getWarningValue();
				}else{
					spCondition = sparepartPreventionConditionDao.selectByPrimaryKey(useWhichWarningValue);
					warningValue = spCondition.getConditionWarningValue();
					isUseSpConfigWarningValue = false;
				}
			
				//告警值的单位是次数
				if(type==2){
					
					if(redis.hexists("point:"+pointCode+":value:prevent", "count")){
						String useTimesString = redis.hget("point:"+pointCode+":value:prevent","count");
						if(useTimesString !=null){
							useCount = Integer.parseInt(useTimesString);
							if(isUseSpConfigWarningValue==true){
								if(isHadWordOrder(spConfig)==false){
									if(useCount >= warningValue){
										addProventionWorkOrder (spConfig,spCondition,isUseSpConfigWarningValue);
									}
								}
							}else{
								if(useCount >= warningValue){
									addProventionWorkOrder (spConfig,spCondition,isUseSpConfigWarningValue);
								}
							}
						}else{
							logger.debug("redis中point:"+pointCode+"使用次数的值为空");
						}
					}else{
						logger.debug("redis中hash键："+"point:"+pointCode+":value:prevent"+"不存在"+",或者该键的字段：count不存在");
					}
				}
				//告警值的单位是小时
				if(type==1){
					if(redis.hexists("point:"+pointCode+":value:prevent", "startTime")&&redis.hexists("point:"+pointCode+":value:prevent", "endTime")){
						String startTimeString = redis.hget("point:"+pointCode+":value:prevent", "startTime");
						String endTimeString = redis.hget("point:"+pointCode+":value:prevent", "endTime");
						if(startTimeString!=null&&endTimeString!=null){
							int startTime = Integer.parseInt(startTimeString);
							int endTime = Integer.parseInt(endTimeString);
							useTime = (endTime - startTime);
							if(isUseSpConfigWarningValue==true){
								if(isHadWordOrder(spConfig)==false){
									if(useTime >= warningValue ){
										addProventionWorkOrder (spConfig,spCondition,isUseSpConfigWarningValue);
									}
								}
							}else{
								if(useTime >= warningValue){
									addProventionWorkOrder (spConfig,spCondition,isUseSpConfigWarningValue);
								}
							}
						}else{
							logger.debug("redis中point:"+pointCode+"开始时间或者结束时间的值为空");
						}
					}else{
						logger.debug("redis中hash键："+"point:"+pointCode+":value:prevent"+"不存在"+",或者该键的字段：startTime不存在,或者该键的字段：endTime不存在");
					}
				}
			}
		}catch(Exception ex){
			logger.error("PreventQuartzJob method:execute", ex);
		}finally {
			jedisPool.returnResource(redis);
		}	
	}
	//得到sparepart_prevention_config表里面每一条记录
	public List<SparepartPreventionConfig> getSparepartPreventionConfigList(){
		return sparepartPreventionConfigLogic.selectList(sparepartPreventionConfig,false);
	}
	
	//添加工单
	public void addProventionWorkOrder (SparepartPreventionConfig spConfig,SparepartPreventionCondition spCondition,boolean isUseSpConfigWarningValue){	
		
		String customerCode = spConfig.getCustomerCode();
		String equipmentCode = spConfig.getEquipmentCode();
		String sparepartCode = spConfig.getSparepartCode();
		String pointCode = spConfig.getPointCode();
		String content;
		
		if(isUseSpConfigWarningValue == true){
			content = spConfig.getWarningContent();
		}else{
			content= spCondition.getConditionWarningContent();
		}
		
		Equipments e = new Equipments();
		e.setCode(equipmentCode);
		e.setLanguage("cn");
		Equipments equipment = equipmentsLogic.select(e);
		String paddingBy = equipment.getCustomerPerson();
		String euipmentName = equipment.getName();
		
		EquipmentBoms ebs = new EquipmentBoms();
		ebs.setCode(sparepartCode);
		ebs.setLanguage("cn");
		EquipmentBoms equipmentBom = equipmentBomsLogic.select(ebs);
		String equipmentBomName = equipmentBom.getName();
		
		EquipmentPoints ep = new EquipmentPoints();
		ep.setCode(pointCode);
		ep.setLanguage("cn");
		EquipmentPoints equipmentPoint = equipmentPointLogic.select(ep);
		String pointName = equipmentPoint.getName();
			
		PreventionWorkOrder pwo = new PreventionWorkOrder();
		pwo.setCode(CodeUtil.flmCode(digit));
		pwo.setCustomerCode(customerCode);
		pwo.setEquipmentCode(equipmentCode);
		pwo.setSparepartCode(sparepartCode);
		pwo.setTitle("设备："+euipmentName+" 原料："+equipmentBomName+" 点位："+pointName+" 告警");
		pwo.setContent(content);
		pwo.setOrderStatus(CommonUtils.ORDER_STATUS_NEW);
		pwo.setPaddingBy(paddingBy);
		pwo.setStatus(CommonUtils.STATUS_NORMAL);
		pwo.setComment(CommonUtils.ORDER_STATUS_NEW_MSG);
		
		preventionWorkOrderDao.insert(pwo);
		
		if(isUseSpConfigWarningValue == true){
			spConfig.setIsHadWorkOrder(1);
			sparepartPreventionConfigLogic.update(spConfig);
		}else{
			spCondition.setIsHadWorkOrder(1);
			sparepartPreventionConditionDao.updateByCondition(spCondition);
		}
	}

	//该配置是否已经生成工单且未处理
	public boolean isHadWordOrder(SparepartPreventionConfig spConfig){

		if(spConfig.getIsHadWorkOrder() == 0){
			return false;
		}
		return true;
	}
	
	//该条件是否已经生成过工单且未处理
	public boolean isHadWordOrder(SparepartPreventionCondition spCondition){
		if(spCondition.getIsHadWorkOrder() == 0){
			return false;
		}
		return true;
	}
	

	//判断配置的条件来确定使用默认告警值还是条件配置里面加的告警值
	public int useWhichWarningValue(SparepartPreventionConfig spConfig,Jedis redis){
		int spConfigId = spConfig.getId();
		List<SparepartPreventionCondition> sparepartPreventionConditionList = sparepartPreventionConditionDao.selectListByConfigId(spConfigId);
		
		if(sparepartPreventionConditionList.size()==0){
			return -1;//没有配置条件告警值，就用默认告警值
		}else{
			for(int i = 0 ; i < sparepartPreventionConditionList.size();i++){
				SparepartPreventionCondition sparepartPreventionCondition = sparepartPreventionConditionList.get(i);
				
				//该条件如果生成过告警的工单，就不用再判断是否符合告警的条件了
				if(isHadWordOrder(sparepartPreventionCondition)==false){
					String[] formulas = sparepartPreventionCondition.getFormula().split("\\|");
					if(formulas.length <= 3){
						continue;
					}
					boolean flag = false;
					//判断是否符合配置的条件
					for(int j = 0; j <formulas.length;j++){
						String[] formula = formulas[j].split(","); 
						String formulaPointCode = formula[0];
						String formulaOperator = formula[2];
						int formulaValue = Integer.parseInt(formula[3]);
						
						if(redis.exists("point:"+formulaPointCode+":value")==true){
						
							String realPointValueString = redis.lindex("point:"+formulaPointCode+":value", 0).split(",")[1];//这里用的最新的实时数据，要改成平均值
							if(realPointValueString!=null){
								int realPointValue = Integer.parseInt(realPointValueString);
								if(formulaOperator.equals(">")){
									if(realPointValue > formulaValue){
										flag = true ;
									}else{
										flag = false ;
										break;
									}
								}
								if(formulaOperator.equals("<")){
									if(realPointValue < formulaValue){
										flag = true ;
									}else{
										flag = false ;
										break;
									}
								}
								if(formulaOperator.equals(">=")){
									if(realPointValue >= formulaValue){
										flag = true ;
									}else{
										flag = false ;
										break;
									}
								}
								if(formulaOperator.equals("<=")){
									if(realPointValue <= formulaValue){
										flag = true ;
									}else{
										flag = false ;
										break;
									}
								}
								if(formulaOperator.equals("=")){
									if(realPointValue == formulaValue){
										flag = true ;
									}else{
										flag = false ;
										break;
									}
								}
							}else{
								logger.debug("redis中点位："+"键point:"+formulaPointCode+":value"+"没有值。");
							}
						}else{
							logger.debug("redis中点位："+"键point:"+formulaPointCode+":value"+"不存在");
						}
					}
					//如果符合配置的条件，返回该条件的告警值
					if(flag == true){
						return sparepartPreventionCondition.getId();
					}
				}
			}
			return -1;
		}
	}
}
